# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: leon

import os
import math
import datetime

from absl import app, flags

import pandas
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from coin.base.datetime_util import to_datetime
from coin.support.feed_tool.feed_stats.logic.util import datetime_span

FLAGS = flags.FLAGS


def plot_col1_vs_col2(df, csv_root, col1, col2, symbol):
  fig, ax1 = plt.subplots(figsize=(20, 10))

  ax2 = ax1.twinx()
  plt.title('Bitmex %s %s VS %s' % (symbol, col1, col2))
  ax1.plot(df.index, df[col1], color='g', marker='.')
  ax2.plot(df.index, df[col2], color='r', marker='.')
  tick_space = (ax1.get_yticks()[-1] - ax1.get_yticks()[0]) / 20
  tick_space = int(math.ceil(tick_space / 5)) * 5
  ax1.yaxis.set_major_locator(ticker.MultipleLocator(tick_space))

  ax1.set_ylabel(col1, color='g')
  ax1.grid(True)
  ax2.set_ylabel(col2, color='r')
  plt.savefig(os.path.join(csv_root, 'Bitmex_%s_%s_vs_%s.png' % (symbol, col1, col2)))


def plot_df(df, csv_root, symbol):
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'funding_rate', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'indicative_funding_rate', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'fair_basis_rate', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'mid_price', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'last_price', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'fair_price', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'open_interest', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'last_change_percent', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'volume24h', symbol)
  plot_col1_vs_col2(df, csv_root, 'mid_price', 'turnover24h', symbol)


def hour_describe(df, symbol):
  pandas.set_option('display.width', 1000)
  start = to_datetime(int(df.iloc[0]['timestamp']))
  end = to_datetime(int(df.iloc[-1]['timestamp']))
  prev_dt = start
  start_hour = start.hour
  start_hour = start.replace(hour=start_hour + 1, minute=0, second=0, microsecond=0)
  end_hour = end.replace(minute=0, second=0, microsecond=0)
  print('Hour describe for %s:' % symbol)
  # timestamp column does not need to describe.
  df = df.drop('timestamp', axis=1)
  for dt in datetime_span(start_hour, end_hour, datetime.timedelta(hours=1)):
    print('%s - %s' % (prev_dt, dt))
    print(df.between_time(prev_dt.time(), dt.time()).describe())
    print()
    prev_dt = dt

  # For the last hour.
  print('%s - %s' % (prev_dt, end))
  print(df.between_time(prev_dt.time(), end.time()).describe())


def daily_describe(df, symbol):
  pandas.set_option('display.width', 1000)
  start = to_datetime(int(df.iloc[0]['timestamp']))
  end = to_datetime(int(df.iloc[-1]['timestamp']))
  print('Daily describe for %s:' % symbol)
  df = df.drop('timestamp', axis=1)
  print('%s - %s' % (start, end))
  print(df.between_time(start.time(), end.time()).describe())
  print()


def sample_df_per_second(df):
  return df.resample('S', closed='left', label='left').last()


def read_csv_into_df(csv_root, csv):
  csv_dir = os.path.join(csv_root, csv)
  df = pandas.read_csv(csv_dir, sep=',', header=0)
  df['datetime'] = pandas.to_datetime(df['timestamp'], unit='ns')
  df = df.set_index('datetime')
  assert len(df) > 0, 'Empty instrument csv: %s' % csv_dir
  return df


def main(argv):
  csv_root = FLAGS.csv_root
  csv = FLAGS.csv
  assert csv_root, '--csv_root must be specified.'
  assert csv, '--csv must be specified.'

  df = read_csv_into_df(csv_root, csv)
  sampled_df = sample_df_per_second(df)
  symbol, *_ = csv.split('.', 1)

  # Put output plot into same csv_root directory.
  plot_df(sampled_df, csv_root, symbol)
  daily_describe(df, symbol)
  hour_describe(df, symbol)

  return 0


if __name__ == '__main__':
  flags.DEFINE_string('csv_root', None, 'Input csv root directory.')

  flags.DEFINE_string('csv', None, 'Input csv file name.')

  app.run(main)
